package com.my.lock.v1;

import com.google.common.base.Throwables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Random;

/**
 * Created by ZhongGang
 * at 2018/7/27 10:39
 */
public class Queue<E> {
    private static final Logger LOGGER = LoggerFactory.getLogger(Queue.class);

    private Object[] elements;//集合元素
    private int count;//集合中元素个数
    private NonReentrantLock lock = new NonReentrantLock();

    public Queue(int size) {
        this.elements = new Object[size];
    }

    public void put(E e) throws InterruptedException {
        try {
            this.lock.lock();

            this.elements[this.count++] = e;

            LOGGER.info("{}", this);

            Thread.sleep(3 * 1000);//模拟耗时操作，查看并发执行情况
        } finally {
            this.lock.unlock();
        }
    }

    @Override
    public String toString() {
        return "Queue{" +
                "elements=" + Arrays.toString(elements) +
                ", count=" + count +
                '}';
    }

    public E take() {
        try {
            this.lock.lock();

            int position = --this.count;
            E e = (E) this.elements[position];
            this.elements[position] = null;
            return e;
        } finally {
            this.lock.unlock();
        }


    }

    public static void main(String[] args) throws Exception {
        Random random = new Random();
        Queue<Integer> queue = new Queue<>(20);
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        queue.put(random.nextInt(100));
                    } catch (InterruptedException e) {
                        LOGGER.error("exception caught, the error is {}", Throwables.getStackTraceAsString(e));
                    }
                }
            }).start();
        }
    }
}
